#include "device.h"
#include "component.h"
#include "wifi_cfg.h"

#define WIFI_CFG_LOG(format, ...) OSAL_LOG(C_PURPLE format C_NONE, ##__VA_ARGS__)

static SuperQueueHandle_t wifi_cfg_queue = NULL;

/**
  * @brief  WIFI CFG中断处理
  * @note   将wifi cfg底层抛上来的数据缓存至队列
  * @return 
  */
static void WiFiCfgComp_IrqHandler(VirtualHardware_enum_t dev, void *pBuf, uint32_t len)
{
    uint16_t type     = len >> 16;
    uint16_t lenght   = (len & 0xFFFF);
    WifiCfgMsg_t *msg = (uint8_t *)OSAL_Malloc(lenght + 1);

    if (msg == NULL)
    {
        return;
    }

    //< 数据缓存至队列
    memset(msg, 0, lenght + 1);
    msg->msg_type = type;
    memcpy(msg->data, pBuf, lenght);
    if (OSAL_QueueSendToBack(wifi_cfg_queue, msg, lenght + 1) == SUCCESS)
    {
        OSAL_EventCreateFromISR(COMP_WIFI_CFG);
    }
    OSAL_Free(msg);
}

/**
  * @brief  wifi初始化
  * @note   
  * @return 
  */
static void WiFiCfgComp_Init(void)
{
    /* 创建队列、注册中断回调 */
    if (wifi_cfg_queue == NULL)
    {
        wifi_cfg_queue = OSAL_QueueCreate(20);
        Device_RegisteredCB(vWIFI_1, WiFiCfgComp_IrqHandler);
    }
}

/**
  * @brief  开启AP
  * 
  * @param  cfginfo 配网所需的信息
  */
static void WiFiCfgComp_Start_Ap(Ap_Cfg_Lock_Info *cfginfo)
{
    /* 开启AP */
    Device_Write(vWIFI_1, cfginfo, sizeof(Ap_Cfg_Lock_Info), WIFI_CFG_CTRL_AP_START);
}

/**
  * @brief  关闭AP
  * 
  * @param
  */
static void WiFiCfgComp_Stop_Ap(void)
{
    /* 关闭AP */
    Device_Write(vWIFI_1, NULL, 0, WIFI_CFG_CTRL_AP_STOP);
}

/**
  * @brief  同步配网信息
  * 
  * @param  cfginfo 配网所需的信息
  */
static void WiFiCfgComp_Sync_Info(Ap_Cfg_Lock_Info *cfginfo)
{
    Device_Write(vWIFI_1, cfginfo, sizeof(Ap_Cfg_Lock_Info), WIFI_CFG_CTRL_SYNC_INFO);
}

/**
  * @brief  处理邮箱发来的数据
  * 
  * @note
  */
static void WiFiCfgComp_ProcessMbox(uint8_t *msg)
{
    switch (msg[0])
    {
        case WIFI_CFG_CTRL_AP_START: //< 开启AP
            WiFiCfgComp_Start_Ap((Ap_Cfg_Lock_Info *)(&msg[1]));
            break;

        case WIFI_CFG_CTRL_AP_STOP:
            WiFiCfgComp_Stop_Ap();
            break;

        case WIFI_CFG_CTRL_SYNC_INFO:
            WiFiCfgComp_Sync_Info((Ap_Cfg_Lock_Info *)(&msg[1]));
            break;

        default:
            break;
    }
}

/**
  * @brief  WifiCfg接收邮箱
  *
  * @return NONE
  */
static void WiFiCfgComp_RecvMbox(void)
{
    uint16_t size = 0;
    while (OSAL_MboxLenght(&size) > 0)
    {
        void *buffer = OSAL_Malloc(size);
        if (buffer != NULL)
        {
            memset(buffer, 0, size);
            OSAL_MboxAccept(buffer);
            WiFiCfgComp_ProcessMbox((uint8_t *)buffer);
            OSAL_Free(buffer);
        }
        else
        {
            WIFI_CFG_LOG("malloc error\r\n");
        }
    }
}

/**
  * @brief  处理wifi cfg底层上报的数据
  * @note
  * @return 
  */
static void WiFiCfgComp_ParseRxPacket(void)
{
    uint16_t len;

    while (OSAL_QueueLenght(wifi_cfg_queue, &len) > 0)
    {
        WifiMsg_t *packet = (WifiMsg_t *)OSAL_Malloc(len);
        if (packet != NULL)
        {
            memset(packet, 0, len);
            len = OSAL_QueueReceive(wifi_cfg_queue, packet);

            WIFI_CFG_LOG("wifi cfg event: %d\r\n", packet->msg_type);
            if (packet->msg_type == WIFI_CFG_MSG_AP_STA_ADD) //有设备连接
            {
                ///< Try to connect to the server
                Device_Write(vWIFI_1, NULL, 0, WIFI_CFG_CTRL_TRY_CONNECT_SERVER);
            }
            else
            {
                ///< nothing here
            }
            OSAL_MessagePublish(packet, len);
            OSAL_Free(packet);
        }
    }
}

/**
  * @brief  Wifi ap 配网任务函数
  *
  * @note
  *
  * @param  event：当前任务的所有事件
  *
  * @return 返回未处理的事件
  */
static uint32_t Wifi_Cfg_Task(uint32_t event)
{
    /* 系统启动事件 */
    if (event & EVENT_SYS_START)
    {
        WIFI_CFG_LOG("wifi cfg task start\r\n");
        WiFiCfgComp_Init();
        Device_Enable(vWIFI_1);
        return (event ^ EVENT_SYS_START);
    }

    /* 系统邮箱事件 */
    if (event & EVENT_SYS_MBOX)
    {
        WiFiCfgComp_RecvMbox();
        return (event ^ EVENT_SYS_MBOX);
    }

    /* wifi中断事件 */
    if (event & EVENT_SYS_ISR)
    {
        WIFI_CFG_LOG("wifi isr event");
        WiFiCfgComp_ParseRxPacket();
        return (event ^ EVENT_SYS_ISR);
    }

    if (event & EVENT_SYS_SLEEP)
    {
        WIFI_CFG_LOG("wifi task sleep\r\n");
        Device_Disable(vWIFI_1);
        return (event ^ EVENT_SYS_SLEEP);
    }
    return 0;
}
COMPONENT_TASK_EXPORT(COMP_WIFI_CFG, Wifi_Cfg_Task, 0);

char import_kos_wifi_cfg;